/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.rhythm.commons.sql;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @param T 
 * @author mlee
 */
public class QueryResult<T>
{
    
    List<T> results;
    Object type;
   
    public QueryResult(List results)
    {        
        this.results = results;
    }
    
    public List<T> getResults()
    {
        if (this.results == null)
            this.results = new ArrayList<T>();
        
        return this.results;
    }
        
    /**
     * Method returns a generic object if the current object's context only
     * contains a single value.  If the current object's context does not
     * contain exactly one value the this method will return NULL
     * 
     * @param type The generic type that the method is expected to return
     * @return An instance of a single object in the current object context
     */
    public  < T > T getSingleResult(Boolean useStrictRules)
    {
        if (this.results == null) return null;
        
        if (this.results.size() == 0) return null;
        
        if (this.results.size() == 1)
        {
            T obj = (T) this.results.get(0);
            return obj;
        }
        
        if (useStrictRules)
            return null;
        else
            return (T) this.results.get(0);
        
        
 
    }
    
    public Boolean hasResults()
    {
        return ((results.size() == 0)? false:true);
    }
    
    public List<T> narrow(String field, Object value) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException
    {
        
        
        List<T> narrowList = new ArrayList<T>();
        //narrowList.add(item);
        String getField = ((field.substring(0, 2).equals("get"))? field:"get" + field);
                
        
        for (int i = 0; i < this.results.size(); i++)
        {
            
           T item = this.results.get(i);
          
           Method method = item.getClass().getMethod(getField, new Class[]{});
           Object methodValud = method.invoke(item, new Object[] {});
           
           if (value.equals(methodValud))
               narrowList.add(this.results.get(i));
           
        }
        
        return narrowList;
        
    }
    

    
}
